#ifndef _ACE_MESH_TASK_
#define _ACE_MESH_TASK_

#ifdef __cplusplus
extern "C" {
#endif

#include "task.h"

//#ifdef SEG_BUFF
//#define SEG_MASTER 1
//#endif
////for task type
//typedef int task_type; 
//#define NOT_SET 0
//#define STENCIL_TASK    1
//#define NOAFFINITY_TASK 2
//#define BLOCKING_TASK 3  
//#define COMPOSITE_TASK 4
//#define COMPOSITE_END_TASK 5
//
//#define ADDR_CHUNKINIT 27
//#define ADDR_CHUNKMORE 5
//
//#ifdef SUPPORT_PARTITION
//#define NO_SET_PART_ID -1
//#endif
//
//#ifdef ACEMESH_PARA
////__threal_local_fix long cur_time;
//#define  BUF_SIZE 2048
//#define MAXT 10000000
//#endif

#ifdef SAVE_RW_INFO
typedef struct addr_info
{
   void* addr;//
   int area_type;
   int rw_type;//r, w, rw,etc
   int is_neighbor;//
}addr_info;
#endif
typedef struct aceMesh_task
{
    struct task task_base;
    //int loop_count;	//add by gxr 2017/03/13
#ifdef SUPPORT_PARTITION
    int my_part_id; 
#endif

#ifdef AUTO_PARTITION
    int group_id;
#endif
    int loop_id;
    int task_id;
#ifdef DEBUG_GRAPH
    int is_joint;
    int ref_count_for_check;
    // int loop_id;
    // int task_id;
#endif
    int capacity_addrs;
    struct task **successor_tasks;
    int successor_count;
    struct task* vertical_task;
    task_type my_type;
    struct aceMesh_task * last_successor;
#ifdef ACEMESH_SCHEDULER_PROFILING
    int reuse_distance;
#endif
#ifdef SAVE_RW_INFO
    struct addr_info *rw_addrs;
    int rw_addrs_count;
#endif
#ifdef MPI_SURPPORT
    int suspend;
#endif

}aceMesh_task;

int get_loop_id(struct aceMesh_task* self);

int get_task_id(struct aceMesh_task* self);

#ifdef SAVE_RW_INFO
    struct addr_info* addr_info_constructor(void* addr, int area_type, int rw_type, int is_neighbor);
#endif

#ifdef SUPPORT_PARTITION
inline void set_part_id(struct aceMesh_task* self,int id)
{
	self->my_part_id = id;
}
inline int get_part_id(struct aceMesh_task* self)
{ 
    return self->my_part_id;
}
#endif

#ifdef AUTO_PARTITION
inline void set_group_id(struct aceMesh_task* self,int id)
{
    self->group_id = id;
}
inline int get_group_id(struct aceMesh_task* self)
{ 
    return self->group_id;
}
#endif

#ifdef DEBUG_GRAPH
void set_joint(struct aceMesh_task* self);
void dfs(struct aceMesh_task* self, int* task_nums, int deep_length);
#endif

struct task *slave_execute(struct aceMesh_task *self);
struct task *execute(struct aceMesh_task *self);

//void set_task_type(struct aceMesh_task* self,task_type type);
task_type get_task_type(struct aceMesh_task* self);

int  get_total_successor_sum(struct aceMesh_task* self);

#if defined(DYNAMIC_SCHEDULER)
void set_affinity_id(struct aceMesh_task* self, int id){}
#endif

#ifdef PAPI_PERFORMANCE
void papi_performance_start();
void papi_performance_end();
#endif

#ifdef SUCC_BATCH
typedef struct m2s_detail{
	int task_num;
#ifdef SUCC_BATCH_V1	
	int is_pending; 
#endif
	struct task *task_detail[PENDING_TASK_NUM];
}m2s_detail;
#endif

#ifdef __cplusplus
}
#endif

#endif
